
import java.io.IOException;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.output.XMLOutputter;

public class GetNewReleases {

    private String[][] browseNodeInfo = {
        {"1", "Arts & Photography"},
        {"2", "Biographies & Memoirs"},
        {"3", "Business & Investing"},
        {"4", "Children's Books"},
        {"4366", "Comics & Graphic Novels"},
        {"5", "Computers & Internet"},
        {"6", "Cooking, Food & Wine"},
        {"86", "Entertainment"},
        {"301889", "Gay & Lesbian"},
        {"10", "Health, Mind & Body"},
        {"9", "History"},
        {"48", "Home & Garden"},
        {"10777", "Law"},
        {"17", "Literature & Fiction"},
        {"13996", "Medicine"},
        {"18", "Mystery & Thrillers"},
        {"53", "Nonfiction"},
        {"290060", "Outdoors & Nature"},
        {"20", "Parenting & Families"},
        {"173507", "Professional & Technical"},
        {"21", "Reference"},
        {"22", "Religion & Spirituality"},
        {"23", "Romance"},
        {"75", "Science"},
        {"25", "Science Fiction & Fantasy"},
        {"26", "Sports"},
        {"28", "Teens"},
        {"27", "Travel"}
    };

    public static void main(String[] args) throws IOException {
        GetNewReleases api = new GetNewReleases();

        Calendar august = Calendar.getInstance();
        august.clear();
        august.set(2011, Calendar.AUGUST, 1);

        Document doc = api.getNewReleaseBySubject("9", august);
        XMLOutputter outputter = new XMLOutputter();
        outputter.output(doc, System.out);
    }

    public Document getNewReleaseBySubject(String browseNodeId, Calendar sinceDate) {

        Document doc = new Document();
        doc.setRootElement(new Element("books"));

        HashMap<String, String> params = new HashMap<String, String>();
        params.put("Service", "AWSECommerceService");
        params.put("Operation", "ItemSearch");
        params.put("Version", "2011-08-11");
        params.put("SearchIndex", "Books");
        //params.put("Condition", "All");
        //params.put("Availability", "Offers");
        params.put("BrowseNode", browseNodeId);
        //params.put("Sort", "daterank");
        params.put("Sort", "-publication_date");
        //params.put("Availability", "");
        params.put("ItemPage", "1");
        params.put("ResponseGroup", "Large");
        params.put("AWSAccessKeyId", "AKIAJMSSTEDH23JSOXFQ");

        AWSAPICall apiCall = new AWSAPICall();

        Calendar bookPublishedDate = Calendar.getInstance();
        bookPublishedDate.clear();
        bookPublishedDate.set(Calendar.SECOND, 1);

        Calendar today = Calendar.getInstance();

        Namespace ns = Namespace.getNamespace("http://webservices.amazon.com/AWSECommerceService/2011-04-01");

        LOOP_PAGES:
        for (int i = 1; i <= 10000; i++) {
            params.put("ItemPage", String.valueOf(i));
            Document doc2 = apiCall.getResponseDOM(params);

            // check if there is an error in the response
            Element errors = doc2.getRootElement().getChild("Items", ns).getChild("Request", ns).getChild("Errors", ns);
            if (errors != null) {
                List<Element> errorList = errors.getChildren("Error", ns);
                if (errorList != null) {
                    for (Element error : errorList) {
                        Logger.getLogger(GetNewReleases.class.getName()).log(Level.SEVERE, "{0}: {1}", 
                                new Object[]{error.getChildText("Code", ns), error.getChildText("Message", ns)});
                    }
                }
                break LOOP_PAGES;
            }


            // get all the books in that page
            //System.out.println(doc2.getRootElement());
            //System.out.println(doc2.getRootElement().getChild("Items", ns));
            //System.out.println(doc2.getRootElement().getChild("Items", ns).getChildren("Item", ns));
            List<Element> books = doc2.getRootElement().getChild("Items", ns).getChildren("Item", ns);

            LOOP_BOOKS:
            for (Element book : books) {
                // for each book, find its item attributes
                Element itemAttributes = book.getChild("ItemAttributes", ns);
                if (itemAttributes != null) {
                    // if there are item attributes, find the publication date attribute
                    Element publicationDate = itemAttributes.getChild("PublicationDate", ns);
                    if (publicationDate != null) {
                        // the date string can be YYYY-MM-DD or YYYY-MM
                        String d = publicationDate.getTextNormalize();
                        if (d != null && d.length() > 0) {
                            String[] dd = d.split("-");
                            int year = Integer.parseInt(dd[0]);
                            int month = (dd.length <= 1) ? 0 : Integer.parseInt(dd[1]);
                            int date = (dd.length <= 2) ? 1 : Integer.parseInt(dd[2]);

                            bookPublishedDate.set(Calendar.YEAR, year);
                            bookPublishedDate.set(Calendar.MONTH, month - 1);
                            bookPublishedDate.set(Calendar.DAY_OF_MONTH, date);

                            if (bookPublishedDate.before(sinceDate)) {
                                Logger.getLogger(GetNewReleases.class.getName()).log(Level.INFO,
                                        "Book before since date: {0} from {1} @ {2}", new Object[]{publicationDate.getTextNormalize(), book.getChildText("ASIN", ns), book.getChildText("DetailPageURL", ns)});
                                break LOOP_PAGES;
                            } else if (bookPublishedDate.before(today)) {
                                doc.getRootElement().addContent(book);
                                Logger.getLogger(GetNewReleases.class.getName()).log(Level.INFO,
                                        "Book included: {0} from {1} @ {2}", new Object[]{publicationDate.getTextNormalize(), book.getChildText("ASIN", ns), book.getChildText("DetailPageURL", ns)});
                            } else {
                                Logger.getLogger(GetNewReleases.class.getName()).log(Level.INFO,
                                        "Book publication date in the future: {0} from {1} @ {2}", new Object[]{publicationDate.getTextNormalize(), book.getChildText("ASIN", ns), book.getChildText("DetailPageURL", ns)});
                            }
                        } else {
                            Logger.getLogger(GetNewReleases.class.getName()).log(Level.INFO,
                                    "Book with strange publication date: {0} from {1} @ {2}", new Object[]{publicationDate.getTextNormalize(), book.getChildText("ASIN", ns), book.getChildText("DetailPageURL", ns)});
                        }
                    } else {
                        Logger.getLogger(GetNewReleases.class.getName()).log(Level.INFO,
                                "Book with no publication date: {0} @ {1}", new Object[]{book.getChildText("ASIN", ns), book.getChildText("DetailPageURL", ns)});
                    }
                } else {
                    Logger.getLogger(GetNewReleases.class.getName()).log(Level.INFO,
                            "Book with no item attributes: {0} @ {1}", new Object[]{book.getChildText("ASIN", ns), book.getChildText("DetailPageURL", ns)});
                }
            }

            if (doc2 == null) {
                break;
            }
        }

        return doc;
    }
}
